﻿module Sustainalytics.LRTM {

    // corresponds to a Long Running Task
    export class LongRunningTaskInstance {

        // task instance status
        public status: LongRunningTaskInstanceStatus;

        // whether current task exists only on client but does not have a corresponding task on server
        public isVirtual: boolean;

        // post information related to creation of current task instance
        public post: LongRunningTaskInstancePost;

        // task instance errors
        public errors: string[] = [];

        // status changed callback
        public statusChangedCallback: (taskInstanceId: string, newStatus: LongRunningTaskInstanceStatusEnum, oldStatus: LongRunningTaskInstanceStatusEnum, taskInstance: LongRunningTaskInstance) => void


        public isDownloadGenerating(): boolean {
            return !this.status.isUpload
                && this.status.isDownload
                && this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Running;
        }

        public isDownloadGenerated(): boolean {
            return !this.status.isUpload
                && this.status.isDownload
                && this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Finished;
        }

        public isDownloadGenerationFailed(): boolean {
            return !this.status.isUpload
                && this.status.isDownload
                && this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Failed;
        }

        public isUploading(): boolean {
            return this.status.isUpload
                && this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Running
                && this.status.taskStatus.progress !== 100;
        }

        public isUploadComplete(): boolean {
            return this.status.isUpload
                && this.status.taskStatus.progress === 100; 
        }

        public isUploadFailed(): boolean {
            return this.status.isUpload
                && this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Failed;
        }


        public isUpload(): boolean {
            return this.status.isUpload;
        }

        public isDownload(): boolean {
            return this.status.isDownload;
        }

        public isScheduled(): boolean {
            return this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Scheduled;
        }

        public isRunning(): boolean {
            return this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Running;
        }

        public isFinished(): boolean {
            return this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Finished;
        }

        public isFailed(): boolean {
            return this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Failed;
        }

        public isCancelled(): boolean {
            return this.status.taskInstanceStatus == LongRunningTaskInstanceStatusEnum.Cancelled;
        }


        public canCancel(): boolean {
            if (this.isUpload()) {
                return true;
            }

            if (this.isDownload()) {
                return this.isDownloadGenerating()
                    || this.isScheduled();
            }

            return this.isRunning() || this.isScheduled();
        }

        public canDownload(): boolean {
            if (this.isDownload()) {
                return this.isDownloadGenerated();
            }

            return false;
        }

        public canClose(): boolean {
            if (this.isUpload()) {
                return this.isUploadComplete()
                    || this.isUploadFailed();
            }

            if (this.isDownload()) {
                return this.isDownloadGenerationFailed()
                    || this.isDownloadGenerated();
            }

            return !this.isRunning();
        }


        public showCancel(): boolean {
            if (this.isUpload()) {
                return true;
            }

            if (this.isDownload()) {
                return this.isDownloadGenerating()
                    || this.isDownloadGenerated()
                    || this.isScheduled();
            }

            return true;
        }

        public showDownload(): boolean {
            if (this.isDownload()) {
                return this.isDownloadGenerating()
                    || this.isDownloadGenerated();
            }

            return false;
        }

        public showClose(): boolean {
            if (this.isUpload()) {
                return this.isUploading()
                    || this.isUploadComplete()
                    || this.isUploadFailed();
            }

            if (this.isDownload()) {
                return this.isDownloadGenerating()
                    || this.isDownloadGenerated()
                    || this.isDownloadGenerationFailed()
            }

            return true;
        }



        // set instance status
        public setStatus(taskInstanceStatus: LongRunningTaskInstanceStatusEnum): void {
            var oldStatus = this.status.taskInstanceStatus;
            this.status.taskInstanceStatus = taskInstanceStatus;

            if (oldStatus !== taskInstanceStatus && this.statusChangedCallback) {
                this.statusChangedCallback(this.status.id, taskInstanceStatus, oldStatus, this);
            }
        }

        // create a virtual task instance
        public static createVirtual(id: string, title: string, taskType: LongRunningTaskTypeEnum, order: number, isUpload: boolean, isDownload: boolean): LongRunningTaskInstance {

            var taskStatus = new LongRunningTaskStatus();

            var taskInstanceStatus = new LongRunningTaskInstanceStatus();
            taskInstanceStatus.taskInstanceStatus = LongRunningTaskInstanceStatusEnum.Running;
            taskInstanceStatus.id = id;
            taskInstanceStatus.title = title;
            taskInstanceStatus.type = taskType;
            taskInstanceStatus.taskStatus = taskStatus;
            taskInstanceStatus.order = order;
            taskInstanceStatus.isUpload = isUpload;
            taskInstanceStatus.isDownload = isDownload;

            var taskInstance = new LongRunningTaskInstance();
            taskInstance.isVirtual = true;
            taskInstance.status = taskInstanceStatus;

            return taskInstance;
        }

        // create task from task instance status obtained from server
        public static createFromServer(taskInstanceStatus: LongRunningTaskInstanceStatus): LongRunningTaskInstance {
            var taskInstance = new LongRunningTaskInstance();
            taskInstance.isVirtual = false;
            taskInstance.status = taskInstanceStatus;
            return taskInstance;
        }

        // sync task instance with server
        public syncWithServer(taskInstanceStatus: LongRunningTaskInstanceStatus) {
            this.status = taskInstanceStatus;
            this.isVirtual = false;
        }
    }
} 